home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Environments / PowerLisp 2.01 / Supplemental Documentation / Documentation / Chapter 19. Structures < prev    next >
Text File  |  1995-03-27  |  49KB  |  1,054 lines

  1. Common Lisp the Language, 2nd Edition
  2. -------------------------------------------------------------------------------
  3.  
  4. 19. Structures
  5.  
  6. Common Lisp provides a facility for creating named record structures with named
  7. components. In effect, the user can define a new data type; every data
  8. structure of that type has components with specified names. Constructor,
  9. access, and assignment constructs are automatically defined when the data type
  10. is defined.
  11.  
  12. This chapter is divided into two parts. The first part discusses the basics of
  13. the structure facility, which is very simple and allows the user to take
  14. advantage of the type-checking, modularity, and convenience of user-defined
  15. record data types. The second part, beginning with section 19.5, discusses a
  16. number of specialized features of the facility that have advanced applications.
  17. These features are completely optional, and you needn't even know they exist in
  18. order to take advantage of the basics.
  19.  
  20. -------------------------------------------------------------------------------
  21.  
  22.    *  Introduction to Structures
  23.    *  How to Use Defstruct
  24.    *  Using the Automatically Defined Constructor Function
  25.    *  Defstruct Slot-Options
  26.    *  Defstruct Options
  27.    *  By-Position Constructor Functions
  28.    *  Structures of Explicitly Specified Representational Type
  29.         o  Unnamed Structures
  30.         o  Named Structures
  31.         o  Other Aspects of Explicitly Specified Structures
  32.  
  33. -------------------------------------------------------------------------------
  34.  
  35. 19.1. Introduction to Structures
  36.  
  37. The structure facility is embodied in the defstruct macro, which allows the
  38. user to create and use aggregate data types with named elements. These are like
  39. ``structures'' in PL/I, or ``records'' in Pascal.
  40.  
  41. As an example, assume you are writing a Lisp program that deals with space
  42. ships in a two-dimensional plane. In your program, you need to represent a
  43. space ship by a Lisp object of some kind. The interesting things about a space
  44. ship, as far as your program is concerned, are its position (represented as x
  45. and y coordinates), velocity (represented as components along the x and y
  46. axes), and mass.
  47.  
  48. A ship might therefore be represented as a record structure with five
  49. components: x-position, y-position, x-velocity, y-velocity, and mass. This
  50. structure could in turn be implemented as a Lisp object in a number of ways. It
  51. could be a list of five elements; the x-position could be the car, the
  52. y-position the cadr, and so on. Equally well it could be a vector of five
  53. elements: the x-position could be element 0, the y-position element 1, and so
  54. on. The problem with either of these representations is that the components
  55. occupy places in the object that are quite arbitrary and hard to remember.
  56. Someone looking at (cadddr ship1) or (aref ship1 3) in a piece of code might
  57. find it difficult to determine that this is accessing the y-velocity component
  58. of ship1. Moreover, if the representation of a ship should have to be changed,
  59. it would be very difficult to find all the places in the code to be changed to
  60. match (not all occurrences of cadddr are intended to extract the y-velocity
  61. from a ship).
  62.  
  63. Ideally components of record structures should have names. One would like to
  64. write something like (ship-y-velocity ship1) instead of (cadddr ship1). One
  65. would also like a more mnemonic way to create a ship than this:
  66.  
  67. (list 0 0 0 0 0)
  68.  
  69. Indeed, one would like ship to be a new data type, just like other Lisp data
  70. types, that one could test with typep, for example. The defstruct facility
  71. provides all of this.
  72.  
  73. defstruct itself is a macro that defines a structure. For the space ship
  74. example, one might define the structure by saying:
  75.  
  76. (defstruct ship
  77.   x-position
  78.   y-position
  79.   x-velocity
  80.   y-velocity
  81.   mass)
  82.  
  83. This declares that every ship is an object with five named components. The
  84. evaluation of this form does several things:
  85.  
  86.    *  It defines ship-x-position to be a function of one argument, a ship, that
  87.      returns the x-position of the ship; ship-y-position and the other
  88.      components are given similar function definitions. These functions are
  89.      called the access functions, as they are used to access elements of the
  90.      structure.
  91.  
  92.    *  The symbol ship becomes the name of a data type of which instances of
  93.      ships are elements. This name becomes acceptable to typep, for example;
  94.      (typep x 'ship) is true if x is a ship and false if x is any object other
  95.      than a ship.
  96.  
  97.    *  A function named ship-p of one argument is defined; it is a predicate
  98.      that is true if its argument is a ship and is false otherwise.
  99.  
  100.    *  A function called make-ship is defined that, when invoked, will create a
  101.      data structure with five components, suitable for use with the access
  102.      functions. Thus executing
  103.  
  104.      (setq ship2 (make-ship))
  105.  
  106.      sets ship2 to a newly created ship object. One can specify the initial
  107.      values of any desired component in the call to make-ship by using keyword
  108.      arguments in this way:
  109.  
  110.      (setq ship2 (make-ship :mass *default-ship-mass*
  111.                             :x-position 0
  112.                             :y-position 0))
  113.  
  114.      This constructs a new ship and initializes three of its components. This
  115.      function is called the constructor function because it constructs a new
  116.      structure.
  117.  
  118.    *  The #S syntax can be used to read instances of ship structures, and a
  119.      printer function is provided for printing out ship structures. For
  120.      example, the value of the variable ship2 shown above might be printed as
  121.  
  122.      #S(ship  x-position 0  y-position 0  x-velocity nil
  123.               y-velocity nil  mass 170000.0)
  124.  
  125.    *  A function called copy-ship of one argument is defined that, when given a
  126.      ship object, will create a new ship object that is a copy of the given
  127.      one. This function is called the copier function.
  128.  
  129.    *  One may use setf to alter the components of a ship:
  130.  
  131.      (setf (ship-x-position ship2) 100)
  132.  
  133.      This alters the x-position of ship2 to be 100. This works because
  134.      defstruct behaves as if it generates an appropriate defsetf form for each
  135.      access function.
  136.  
  137. This simple example illustrates the power of defstruct to provide abstract
  138. record structures in a convenient manner. defstruct has many other features as
  139. well for specialized purposes.
  140.  
  141. -------------------------------------------------------------------------------
  142.  
  143. 19.2. How to Use Defstruct
  144.  
  145. All structures are defined through the defstruct construct. A call to defstruct
  146. defines a new data type whose instances have named slots.
  147.  
  148. [change_begin]
  149.  
  150. [Macro]
  151.  
  152. defstruct name-and-options [doc-string] {slot-description}+
  153.  
  154. X3J13 voted in June 1988 (DEFSTRUCT-SLOTS-CONSTRAINTS-NUMBER)   to allow a
  155. defstruct definition to have no slot-description at all; in other words, the
  156. occurrence of slot-description in the preceding header line would be replaced
  157. by slot-description.
  158.  
  159. Such structure definitions are particularly useful if the :include option is
  160. used, perhaps with other options; for example, one can have two structures that
  161. are exactly alike except that they print differently (having different
  162. :print-function options).
  163.  
  164. Implementors are encouraged to permit this simple extension as soon as
  165. convenient. Users, however, may wish to maximize portability of their code by
  166. avoiding the use of this extension unless and until it is adopted as part of
  167. the ANSI standard.
  168. [change_end]
  169.  
  170. This defines a record-structure data type. A general call to defstruct looks
  171. like the following example.
  172.  
  173. (defstruct (name option-1 option-2 ... option-m)
  174.            doc-string
  175.            slot-description-1
  176.            slot-description-2
  177.            ...
  178.            slot-description-n)
  179.  
  180. The name must be a symbol; it becomes the name of a new data type consisting of
  181. all instances of the structure. The function typep will accept and use this
  182. name as appropriate. The name is returned as the value of the defstruct form.
  183.  
  184. Usually no options are needed at all. If no options are specified, then one may
  185. write simply name instead of (name) after the word defstruct. The syntax of
  186. options and the options provided are discussed in section 19.5.
  187.  
  188. If the optional documentation string doc-string is present, then it is attached
  189. to the name as a documentation string of type structure; see documentation.
  190.  
  191. Each slot-description-j is of the form
  192.  
  193. (slot-name default-init slot-option-name-1 slot-option-value-1
  194. slot-option-name-2 slot-option-value-2 ... slot-option-name-kj
  195. slot-option-value-kj)
  196.  
  197. Each slot-name must be a symbol; an access function is defined for each slot.
  198. If no options and no default-init are specified, then one may write simply
  199. slot-name instead of (slot-name) as the slot description.
  200.  
  201. [old_change_begin]
  202. The default-init is a form that is evaluated each time a structure is to be
  203. constructed; the value is used as the initial value of the slot.
  204. [old_change_end]
  205.  
  206. [change_begin]
  207. X3J13 voted in October 1988 (DEFSTRUCT-DEFAULT-VALUE-EVALUATION)   to clarify
  208. that a default-init form is evaluated only if the corresponding argument is not
  209. supplied to the constructor function. The preceding sentence should therefore
  210. read as follows:
  211.  
  212. The default-init is a form that is evaluated each time its value is to be used
  213. as the initial value of the slot.
  214. [change_end]
  215.  
  216. If no default-init is specified, then the initial contents of the slot are
  217. undefined and implementation-dependent. The available slot-options are
  218. described in section 19.4.
  219.  
  220. -------------------------------------------------------------------------------
  221. Compatibility note: Slot-options are not currently provided in Lisp Machine
  222. Lisp, but this is an upward-compatible extension.
  223. -------------------------------------------------------------------------------
  224.  
  225. [change_begin]
  226. X3J13 voted in January 1989 (DEFSTRUCT-SLOTS-CONSTRAINTS-NAME)   to specify
  227. that it is an error for two slots to have the same name; more precisely, no two
  228. slots may have names for whose print names string= would be true. Under this
  229. interpretation
  230.  
  231. (defstruct lotsa-slots slot slot)
  232.  
  233. obviously is incorrect but the following one is also in error, even assuming
  234. that the symbols coin:slot and blot:slot really are distinct (non-eql) symbols:
  235.  
  236. (defstruct no-dice coin:slot blot:slot)
  237.  
  238. To illustrate another case, the first defstruct form below is correct, but the
  239. second one is in error.
  240.  
  241. (defstruct one-slot slot) (defstruct (two-slots (:include one-slot)) slot)
  242.  
  243. -------------------------------------------------------------------------------
  244. Rationale: Print names are the criterion for slot-names being the same, rather
  245. than the symbols themselves, because defstruct constructs names of accessor
  246. functions from the print names and interns the resulting new names in the
  247. current package.
  248. -------------------------------------------------------------------------------
  249.  
  250. X3J13 recommended that expanding a defstruct form violating this restriction
  251. should signal an error and noted, with an eye to the Common Lisp Object System
  252. (CLOS)   , that the restriction applies only to the operation of the defstruct
  253. macro as such and not to the structure-class or structures defined with
  254. defclass.
  255.  
  256. X3J13 voted in March 1989 (DEFINING-MACROS-NON-TOP-LEVEL)   to clarify that,
  257. while defining forms normally appear at top level, it is meaningful to place
  258. them in non-top-level contexts; defstruct must treat slot default-init forms
  259. and any initialization forms within the specification of a by-position
  260. constructor function as occurring within the enclosing lexical environment, not
  261. within the global environment.
  262. [change_end]
  263.  
  264. defstruct not only defines an access function for each slot, but also arranges
  265. for setf to work properly on such access functions, defines a predicate named
  266. name-p, defines a constructor function named make-name, and defines a copier
  267. function named copy-name. All names of automatically created functions are
  268. interned in whatever package is current at the time the defstruct form is
  269. processed (see *package*). Also, all such functions may be declared inline at
  270. the discretion of the implementation to improve efficiency; if you do not want
  271. some function declared inline, follow the defstruct form with a notinline
  272. declaration to override any automatic inline declaration.
  273.  
  274. [change_begin]
  275. X3J13 voted in January 1989 (DEFSTRUCT-REDEFINITION)   to specify that the
  276. results of redefining a defstruct structure (that is, evaluating more than one
  277. defstruct structure for the same name) are undefined.
  278.  
  279. The problem is that if instances have been created under the old definition and
  280. then remain accessible after the new definition has been evaluated, the
  281. accessors and other functions for the new definition may be incompatible with
  282. the old instances. Conversely, functions associated with the old definition may
  283. have been declared inline and compiled into code that remains accessible after
  284. the new definition has been evaluated; such code may be incompatible with the
  285. new instances.
  286.  
  287. In practice this restriction affects the development and debugging process
  288. rather than production runs of fully developed code. The defstruct feature is
  289. intended to provide ``the most efficient'' structure class. CLOS classes
  290. defined by defclass allow much more flexible structures to be defined and
  291. redefined.
  292.  
  293. Programming environments are allowed and encouraged to permit defstruct
  294. redefinition, perhaps with warning messages about possible interactions with
  295. other parts of the programming environment or memory state. It is beyond the
  296. scope of the Common Lisp language standard to define those interactions except
  297. to note that they are not portable.
  298. [change_end]
  299.  
  300. -------------------------------------------------------------------------------
  301.  
  302. 19.3. Using the Automatically Defined Constructor Function
  303.  
  304. After you have defined a new structure with defstruct, you can create instances
  305. of this structure by using the constructor function. By default, defstruct
  306. defines this function automatically. For a structure named foo, the constructor
  307. function is normally named make-foo; you can specify a different name by giving
  308. it as the argument to the :constructor option, or specify that you don't want a
  309. normal constructor function at all by using nil as the argument (in which case
  310. one or more ``by-position'' constructors should be requested; see section
  311. 19.6).
  312.  
  313. A call to a constructor function, in general, has the form
  314.  
  315. (name-of-constructor-function
  316.         slot-keyword-1 form-1
  317.         slot-keyword-2 form-2
  318.         ...)
  319.  
  320. All arguments are keyword arguments. Each slot-keyword should be a keyword
  321. whose name matches the name of a slot of the structure (defstruct determines
  322. the possible keywords simply by interning each slot-name in the keyword
  323. package). All the keywords and forms are evaluated. In short, it is just as if
  324. the constructor function took all its arguments as &key parameters. For
  325. example, the ship structure shown in section 19.1 has a constructor function
  326. that takes arguments roughly as if its definition were
  327.  
  328. (defun make-ship (&key x-position y-position
  329.                        x-velocity y-velocity mass)
  330.   ...)
  331.  
  332.   If slot-keyword-j names a slot, then that element of the created structure
  333. will be initialized to the value of form-j. If no pair slot-keyword-j and
  334. form-j is present for a given slot, then the slot will be initialized by
  335. evaluating the default-init form specified for that slot in the call to
  336. defstruct. (In other words, the initialization specified in the defstruct
  337. defers to any specified in a call to the constructor function.) If the default
  338. initialization form is used, it is evaluated at construction time, but in the
  339. lexical environment of the defstruct form in which it appeared. If the
  340. defstruct itself also did not specify any initialization, the element's initial
  341. value is undefined. You should always specify the initialization, either in the
  342. defstruct or in the call to the constructor function, if you care about the
  343. initial value of the slot.
  344.  
  345. Each initialization form specified for a defstruct component, when used by the
  346. constructor function for an otherwise unspecified component, is re-evaluated on
  347. every call to the constructor function. It is as if the initialization forms
  348. were used as init forms for the keyword parameters of the constructor function.
  349. For example, if the form (gensym) were used as an initialization form, either
  350. in the constructor-function call or as the default initialization form in the
  351. defstruct form, then every call to the constructor function would call gensym
  352. once to generate a new symbol.
  353.  
  354. [change_begin]
  355. X3J13 voted in October 1988 (DEFSTRUCT-DEFAULT-VALUE-EVALUATION)   to clarify
  356. that the default value in a defstruct slot is not evaluated unless it is needed
  357. in the creation of a particular structure instance. If it is never needed,
  358. there can be no type-mismatch error, even if the type of the slot is specified,
  359. and no warning should be issued.
  360.  
  361. For example, in the following sequence only the last form is in error.
  362.  
  363. (defstruct person (name .007 :type string))
  364.  
  365. (make-person :name "James")
  366.  
  367. (make-person)     ;Error to give name the value .007
  368.  
  369. [change_end]
  370.  
  371. -------------------------------------------------------------------------------
  372.  
  373. 19.4. Defstruct Slot-Options
  374.  
  375. Each slot-description in a defstruct form may specify one or more slot-options.
  376. A slot-option consists of a pair of a keyword and a value (which is not a form
  377. to be evaluated, but the value itself). For example:
  378.  
  379. (defstruct ship
  380.   (x-position 0.0 :type short-float)
  381.   (y-position 0.0 :type short-float)
  382.   (x-velocity 0.0 :type short-float)
  383.   (y-velocity 0.0 :type short-float)
  384.   (mass *default-ship-mass* :type short-float :read-only t))
  385.  
  386. This specifies that each slot will always contain a short-format floating-point
  387. number, and that the last slot may not be altered once a ship is constructed.
  388.  
  389. The available slot-options are as follows.
  390.  
  391. :type
  392.      The option :type type specifies that the contents of the slot will always
  393.      be of the specified data type. This is entirely analogous to the
  394.      declaration of a variable or function; indeed, it effectively declares the
  395.      result type of the access function. An implementation may or may not
  396.      choose to check the type of the new object when initializing or assigning
  397.      to a slot. Note that the argument form type is not evaluated; it must be a
  398.      valid type specifier.
  399.  
  400. :read-only
  401.      The option :read-only x, where x is not nil, specifies that this slot may
  402.      not be altered; it will always contain the value specified at construction
  403.      time. setf will not accept the access function for this slot. If x is nil,
  404.      this slot-option has no effect. Note that the argument form x is not
  405.      evaluated.
  406.  
  407. Note that it is impossible to specify a slot-option unless a default value is
  408. specified first.
  409.  
  410. -------------------------------------------------------------------------------
  411.  
  412. 19.5. Defstruct Options
  413.  
  414. The preceding description of defstruct is all that the average user will need
  415. (or want) to know in order to use structures. The remainder of this chapter
  416. discusses more complex features of the defstruct facility.
  417.  
  418. This section explains each of the options that can be given to defstruct. A
  419. defstruct option may be either a keyword or a list of a keyword and arguments
  420. for that keyword. (Note that the syntax for defstruct options differs from the
  421. pair syntax used for slot-options. No part of any of these options is
  422. evaluated.)
  423.  
  424. :conc-name
  425.      This provides for automatic prefixing of names of access functions. It is
  426.      conventional to begin the names of all the access functions of a structure
  427.      with a specific prefix, the name of the structure followed by a hyphen.
  428.      This is the default behavior.
  429.  
  430.      The argument to the :conc-name option specifies an alternative prefix to
  431.      be used. (If a hyphen is to be used as a separator, it must be specified
  432.      as part of the prefix.) If nil is specified as an argument, then no prefix
  433.      is used; then the names of the access functions are the same as the
  434.      slot-names, and it is up to the user to name the slots reasonably.
  435.  
  436.      Note that no matter what is specified for :conc-name, with a constructor
  437.      function one uses slot keywords that match the slot-names, with no prefix
  438.      attached. On the other hand, one uses the access-function name when using
  439.      setf. Here is an example:
  440.  
  441.      (defstruct door knob-color width material)
  442.      (setq my-door
  443.            (make-door :knob-color 'red :width 5.0))
  444.      (door-width my-door) => 5.0
  445.      (setf (door-width my-door) 43.7)
  446.      (door-width my-door) => 43.7
  447.      (door-knob-color my-door) => red
  448.  
  449. :constructor
  450.      This option takes one argument, a symbol, which specifies the name of the
  451.      constructor function. If the argument is not provided or if the option
  452.      itself is not provided, the name of the constructor is produced by
  453.      concatenating the string "MAKE-" and the name of the structure, putting
  454.      the name in whatever package is current at the time the defstruct form is
  455.      processed (see *package*). If the argument is provided and is nil, no
  456.      constructor function is defined.
  457.  
  458.      This option actually has a more general syntax that is explained in
  459.      section 19.6.
  460.  
  461. :copier
  462.      This option takes one argument, a symbol, which specifies the name of the
  463.      copier function. If the argument is not provided or if the option itself
  464.      is not provided, the name of the copier is produced by concatenating the
  465.      string "COPY-" and the name of the structure, putting the name in whatever
  466.      package is current at the time the defstruct form is processed (see
  467.      *package*). If the argument is provided and is nil, no copier function is
  468.      defined.
  469.  
  470.      The automatically defined copier function simply makes a new structure and
  471.      transfers all components verbatim from the argument into the newly created
  472.      structure. No attempt is made to make copies of the components.
  473.      Corresponding components of the old and new structures will therefore be
  474.      eql.
  475.  
  476. :predicate
  477.      This option takes one argument, which specifies the name of the type
  478.      predicate. If the argument is not provided or if the option itself is not
  479.      provided, the name of the predicate is made by concatenating the name of
  480.      the structure to the string "-P", putting the name in whatever package is
  481.      current at the time the defstruct form is processed (see *package*). If
  482.      the argument is provided and is nil, no predicate is defined. A predicate
  483.      can be defined only if the structure is ``named''; if the :type option is
  484.      specified and the :named option is not specified, then the :predicate
  485.      option must either be unspecified or have the value nil.
  486.  
  487. :include
  488.      This option is used for building a new structure definition as an
  489.      extension of an old structure definition. As an example, suppose you have
  490.      a structure called person that looks like this:
  491.  
  492.      (defstruct person name age sex)
  493.  
  494.      Now suppose you want to make a new structure to represent an astronaut.
  495.      Since astronauts are people too, you would like them also to have the
  496.      attributes of name, age, and sex, and you would like Lisp functions that
  497.      operate on person structures to operate just as well on astronaut
  498.      structures. You can do this by defining astronaut with the :include
  499.      option, as follows:
  500.  
  501.      (defstruct (astronaut (:include person)
  502.                            (:conc-name astro-))
  503.         helmet-size
  504.         (favorite-beverage 'tang))
  505.  
  506.      The :include option causes the structure being defined to have the same
  507.      slots as the included structure. This is done in such a way that the
  508.      access functions for the included structure will also work on the
  509.      structure being defined. In this example, an astronaut will therefore have
  510.      five slots: the three defined in person and the two defined in astronaut
  511.      itself. The access functions defined by the person structure can be
  512.      applied to instances of the astronaut structure, and they will work
  513.      correctly. Moreover, astronaut will have its own access functions for
  514.      components defined by the person structure. The following examples
  515.      illustrate how you can use astronaut structures:
  516.  
  517.      (setq x (make-astronaut :name 'buzz
  518.                              :age 45
  519.                              :sex t
  520.                              :helmet-size 17.5))
  521.  
  522.      (person-name x) => buzz
  523.      (astro-name x) => buzz
  524.  
  525.      (astro-favorite-beverage x) => tang
  526.  
  527.      The difference between the access functions person-name and astro-name is
  528.      that person-name may be correctly applied to any person, including an
  529.      astronaut, while astro-name may be correctly applied only to an astronaut.
  530.      (An implementation may or may not check for incorrect use of access
  531.      functions.)
  532.  
  533.      At most one :include option may be specified in a single defstruct form.
  534.      The argument to the :include option is required and must be the name of
  535.      some previously defined structure. If the structure being defined has no
  536.      :type option, then the included structure must also have had no :type
  537.      option specified for it. If the structure being defined has a :type
  538.      option, then the included structure must have been declared with a :type
  539.      option specifying the same representation type.
  540.  
  541.      If no :type option is involved, then the structure name of the including
  542.      structure definition becomes the name of a data type, of course, and
  543.      therefore a valid type specifier recognizable by typep; moreover, it
  544.      becomes a subtype of the included structure. In the above example,
  545.      astronaut is a subtype of person; hence
  546.  
  547.      (typep (make-astronaut) 'person)
  548.  
  549.      is true, indicating that all operations on persons will also work on
  550.      astronauts.
  551.  
  552.      The following is an advanced feature of the :include option. Sometimes,
  553.      when one structure includes another, the default values or slot-options
  554.      for the slots that came from the included structure are not what you want.
  555.      The new structure can specify default values or slot-options for the
  556.      included slots different from those the included structure specifies, by
  557.      giving the :include option as
  558.  
  559.      (:include name slot-description-1 slot-description-2 ...)
  560.  
  561.      Each slot-description-j must have a slot-name or slot-keyword that is the
  562.      same as that of some slot in the included structure. If slot-description-j
  563.      has no default-init, then in the new structure the slot will have no
  564.      initial value. Otherwise its initial value form will be replaced by the
  565.      default-init in slot-description-j. A normally writable slot may be made
  566.      read-only. If a slot is read-only in the included structure, then it must
  567.      also be so in the including structure. If a type is specified for a slot,
  568.      it must be the same as, or a subtype of, the type specified in the
  569.      included structure. If it is a strict subtype, the implementation may or
  570.      may not choose to error-check assignments.
  571.  
  572.      For example, if we had wanted to define astronaut so that the default age
  573.      for an astronaut is 45, then we could have said:
  574.  
  575.      (defstruct (astronaut (:include person (age 45)))
  576.         helmet-size
  577.         (favorite-beverage 'tang))
  578.  
  579. [change_begin]
  580.  
  581.      X3J13 voted in June 1988 (DATA-TYPES-HIERARCHY-UNDERSPECIFIED)   to
  582.      require any structure type created by defstruct (or defclass) to be
  583.      disjoint from any of the types cons, symbol, array, number, character,
  584.      hash-table, readtable, package, pathname, stream, and random-state. A
  585.      consequence of this requirement is that it is an error to specify any of
  586.      these types, or any of their subtypes, to the defstruct :include option.
  587.      (The first edition said nothing explicitly about this. Inasmuch as using
  588.      such a type with the :include option was not defined to work, one might
  589.      argue that such use was an error in Common Lisp as defined by the first
  590.      edition.)
  591.  
  592. [change_end]
  593.  
  594. :print-function
  595.      This option may be used only if the :type option is not specified. The
  596.      argument to the :print-function option should be a function of three
  597.      arguments, in a form acceptable to the function special form, to be used
  598.      to print structures of this type. When a structure of this type is to be
  599.      printed, the function is called on three arguments: the structure to be
  600.      printed, a stream to print to, and an integer indicating the current depth
  601.      (to be compared against *print-level*). The printing function should
  602.      observe the values of such printer-control variables as *print-escape* and
  603.      *print-pretty*.
  604.  
  605.      If the :print-function option is not specified and the :type option also
  606.      not specified, then a default printing function is provided for the
  607.      structure that will print out all its slots using #S syntax (see section
  608.      22.1.4).
  609.  
  610. [change_begin]
  611.  
  612.      X3J13 voted in January 1989 (PRINT-CIRCLE-STRUCTURE)   to specify that
  613.      user-defined printing functions for the defstruct :print-function option
  614.      may print objects to the supplied stream using write, print1, princ,
  615.      format, or print-object and expect circularities to be detected and
  616.      printed using #n# syntax (when *print-circle* is non-nil, of course). See
  617.      *print-circle*.
  618.  
  619.      X3J13 voted in January 1989 (DEFSTRUCT-PRINT-FUNCTION-INHERITANCE)   to
  620.      clarify that if the :print-function option is not specified but the
  621.      :include option is specified, then the print function is inherited from
  622.      the included structure type. Thus, for example, an astronaut will be
  623.      printed by the same printing function that is used for person.
  624.  
  625.      X3J13 in the same vote extended the print-function option as follows: If
  626.      the print-function option is specified but with no argument, then the
  627.      standard default printing function (that uses #S syntax) will be used.
  628.      This provides a means of overriding the inheritance rule. For example, if
  629.      person and astronaut had been defined as
  630.  
  631.      (defstruct (person
  632.                   (:print-function     ;Special print function
  633.                   (lambda (p s k)
  634.                     (format s "<~A, age ~D>"
  635.                             (person-name p)
  636.                             (person-age p)))))
  637.        name age sex)
  638.  
  639.      (defstruct (astronaut
  640.                   (:include person)
  641.                   (:conc-name astro-)
  642.                   (:print-function))     ;Use default print function
  643.         helmet-size
  644.         (favorite-beverage 'tang))
  645.  
  646.      then an ordinary person would be printed as ``<Joe Schmoe, age 27>'' but
  647.      an astronaut would be printed as, for example,
  648.  
  649.      #S(ASTRONAUT NAME BUZZ AGE 45 SEX T
  650.         HELMET-SIZE 17.5 FAVORITE-BEVERAGE TANG)
  651.  
  652.      using the default #S syntax (yuk).
  653.  
  654. [change_end]
  655.  
  656. These changes make the behavior of defstruct with respect to the :include
  657. option a bit more like the behavior of classes in CLOS.
  658.  
  659. :type
  660.      The :type option explicitly specifies the representation to be used for
  661.      the structure. It takes one argument, which must be one of the types
  662.      enumerated below.
  663.  
  664.      Specifying this option has the effect of forcing a specific representation
  665.      and of forcing the components to be stored in the order specified in the
  666.      defstruct form in corresponding successive elements of the specified
  667.      representation. It also prevents the structure name from becoming a valid
  668.      type specifier recognizable by typep (see section 19.7).
  669.  
  670.      Normally this option is not specified, in which case the structure is
  671.      represented in an implementation-dependent manner.
  672.  
  673.           vector
  674.                This produces the same result as specifying (vector t). The
  675.                structure is represented as a general vector, storing
  676.                components as vector elements. The first component is
  677.                vector element 1 if the structure is :named, and element 0
  678.                otherwise.
  679.  
  680.           (vector element-type)
  681.                The structure is represented as a (possibly specialized)
  682.                vector, storing components as vector elements. Every
  683.                component must be of a type that can be stored in a vector
  684.                of the type specified. The first component is vector
  685.                element 1 if the structure is :named, and element 0
  686.                otherwise. The structure may be :named only if the type
  687.                symbol is a subtype of the specified element-type.
  688.  
  689.           list
  690.                The structure is represented as a list. The first component
  691.                is the cadr if the structure is :named, and the car if it
  692.                is :unnamed.
  693.  
  694. :named
  695.      The :named option specifies that the structure is ``named''; this option
  696.      takes no argument. If no :type option is specified, then the structure is
  697.      always named; so this option is useful only in conjunction with the :type
  698.      option. See section 19.7 for a further description of this option.
  699.  
  700. :initial-offset
  701.      This allows you to tell defstruct to skip over a certain number of slots
  702.      before it starts allocating the slots described in the body. This option
  703.      requires an argument, a non-negative integer, which is the number of slots
  704.      you want defstruct to skip. The :initial-offset option may be used only if
  705.      the :type option is also specified. See section 19.7.3 for a further
  706.      description of this option.
  707.  
  708. -------------------------------------------------------------------------------
  709.  
  710. 19.6. By-Position Constructor Functions
  711.  
  712. If the :constructor option is given as (:constructor name arglist), then
  713. instead of making a keyword-driven constructor function, defstruct defines a
  714. ``positional'' constructor function, taking arguments whose meaning is
  715. determined by the argument's position rather than by a keyword. The arglist is
  716. used to describe what the arguments to the constructor will be. In the simplest
  717. case something like (:constructor make-foo (a b c)) defines make-foo to be a
  718. three-argument constructor function whose arguments are used to initialize the
  719. slots named a, b, and c.
  720.  
  721. In addition, the keywords &optional, &rest, and &aux are recognized in the
  722. argument list. They work in the way you might expect, but there are a few fine
  723. points worthy of explanation. Consider this example:
  724.  
  725. (:constructor create-foo
  726.         (a &optional b (c 'sea) &rest d &aux e (f 'eff)))
  727.  
  728. This defines create-foo to be a constructor of one or more arguments. The first
  729. argument is used to initialize the a slot. The second argument is used to
  730. initialize the b slot. If there isn't any second argument, then the default
  731. value given in the body of the defstruct (if given) is used instead. The third
  732. argument is used to initialize the c slot. If there isn't any third argument,
  733. then the symbol sea is used instead. Any arguments following the third argument
  734. are collected into a list and used to initialize the d slot. If there are three
  735. or fewer arguments, then nil is placed in the d slot. The e slot is not
  736. initialized; its initial value is undefined. Finally, the f slot is initialized
  737. to contain the symbol eff.
  738.  
  739. The actions taken in the b and e cases were carefully chosen to allow the user
  740. to specify all possible behaviors. Note that the &aux ``variables'' can be used
  741. to completely override the default initializations given in the body.
  742.  
  743. With this definition, one can write
  744.  
  745. (create-foo 1 2)
  746.  
  747. instead of
  748.  
  749. (make-foo :a 1 :b 2)
  750.  
  751. and of course create-foo provides defaulting different from that of make-foo.
  752.  
  753. It is permissible to use the :constructor option more than once, so that you
  754. can define several different constructor functions, each taking different
  755. parameters.
  756.  
  757. Because a constructor of this type operates By Order of Arguments, it is
  758. sometimes known as a BOA constructor.
  759.  
  760. [change_begin]
  761. X3J13 voted in January 1989 (DEFSTRUCT-CONSTRUCTOR-KEY-MIXTURE)   to allow &key
  762. and &allow-other-keys in the parameter list of a ``positional'' constructor.
  763. The initialization of slots corresponding to keyword parameters is performed in
  764. the same manner as for &optional parameters. A variant of the example shown
  765. above illustrates this:
  766.  
  767. (:constructor create-foo
  768.         (a &optional b (c 'sea)
  769.          &key p (q 'cue) ((:why y)) ((:you u) 'ewe)
  770.          &aux e (f 'eff)))
  771.  
  772. The treatment of slots a, b, c, e, and f is the same as in the original
  773. example. In addition, if there is a :p keyword argument, it is used to
  774. initialize the p slot; if there isn't any :p keyword argument, then the default
  775. value given in the body of the defstruct (if given) is used instead. Similarly,
  776. if there is a :q keyword argument, it is used to initialize the q slot; if
  777. there isn't any :q keyword argument, then the symbol cue is used instead.
  778.  
  779. In order thoroughly to flog this presumably already dead horse, we further
  780. observe that if there is a :why keyword argument, it is used to initialize the
  781. y slot; otherwise the default value for slot y is used instead. Similarly, if
  782. there is a :you keyword argument, it is used to initialize the u slot;
  783. otherwise the symbol ewe is used instead.
  784.  
  785. If memory serves me correctly, defstruct was included in the original design
  786. for Common Lisp some time before keyword arguments were approved. The failure
  787. of positional constructors to accept keyword arguments may well have been an
  788. oversight on my part; there is no logical reason to exclude them. I am grateful
  789. to X3J13 for rectifying this.
  790.  
  791. A remaining difficulty is that the possibility of keyword arguments renders the
  792. term ``positional constructor'' a misnomer. Worse yet, it ruins the term ``BOA
  793. constructor.'' I suggest that they continue to be called BOA constructors, as I
  794. refuse to abandon a good pun. (I regret appearing to have more compassion for
  795. puns than for horses.)
  796.  
  797. As part of the same vote X3J13 also changed defstruct to allow BOA constructors
  798. to have parameters (including supplied-p parameters) that do not correspond to
  799. any slot. Such parameters may be used in subsequent initialization forms in the
  800. parameter list. Consider this example:
  801.  
  802. (defstruct (ice-cream-factory
  803.              (:constructor fabricate-factory
  804.                (&key (capacity 5)
  805.                       location
  806.                       (local-flavors
  807.                         (case location
  808.                           ((hawaii) '(pineapple macadamia guava))
  809.                           ((massachusetts) '(lobster baked-bean))
  810.                           ((california) '(ginger lotus avocado
  811.                                           bean-sprout garlic))
  812.                           ((texas) '(jalapeno barbecue))))
  813.                       (flavors (subseq (append local-flavors
  814.                                                '(vanilla
  815.                                                  chocolate
  816.                                                  strawberry
  817.                                                  pistachio
  818.                                                  maple-walnut
  819.                                                  peppermint))
  820.                                        0 capacity)))))
  821.   (capacity 3)
  822.   (flavors '(vanilla chocolate strawberry mango)))
  823.  
  824. The structure type ice-cream-factory has two constructors. The standard
  825. constructor, make-ice-cream-factory, takes two keyword arguments named
  826. :capacity and :flavors. For this constructor, the default for the capacity slot
  827. is 3 and the default list of flavors is America's favorite threesome and a dark
  828. horse (not a dead one). The BOA constructor fabricate-factory accepts four
  829. different keyword arguments. The :capacity argument defaults to 5, and the
  830. :flavors argument defaults in a complicated manner based on the other three.
  831. The :local-flavors argument may be specified directly, or may be allowed to
  832. default based on the :location of the factory. Here are examples of various
  833. factories:
  834.  
  835. (setq houston (fabricate-factory :capacity 4 :location 'texas))
  836. (setq cambridge (fabricate-factory :location 'massachusetts))
  837. (setq seattle (fabricate-factory :local-flavors '(salmon)))
  838. (setq wheaton (fabricate-factory :capacity 4 :location 'illinois))
  839. (setq pittsburgh (fabricate-factory :capacity 4))
  840. (setq cleveland (make-factory :capacity 4))
  841.  
  842. (ice-cream-factory-flavors houston)
  843.  => (jalapeno barbecue vanilla chocolate)
  844.  
  845. (ice-cream-factory-flavors cambridge)
  846.  => (lobster baked-bean vanilla chocolate strawberry)
  847.  
  848. (ice-cream-factory-flavors seattle)
  849.  => (salmon vanilla chocolate strawberry pistachio)
  850.  
  851. (ice-cream-factory-flavors wheaton)
  852.  => (vanilla chocolate strawberry pistachio)
  853.  
  854. (ice-cream-factory-flavors pittsburgh)
  855.  => (vanilla chocolate strawberry pistachio)
  856.  
  857. (ice-cream-factory-flavors cleveland)
  858.  => (vanilla chocolate strawberry mango)
  859.  
  860. [change_end]
  861.  
  862. -------------------------------------------------------------------------------
  863.  
  864. 19.7. Structures of Explicitly Specified Representational Type
  865.  
  866. Sometimes it is important to have explicit control over the representation of a
  867. structure. The :type option allows one to specify that a structure must be
  868. implemented in a particular way, using a list or a specific kind of vector, and
  869. to specify the exact allocation of structure slots to components of the
  870. representation. A structure may also be ``unnamed'' or ``named,'' according to
  871. whether the structure name is stored in (and thus recoverable from) the
  872. structure.
  873.  
  874. -------------------------------------------------------------------------------
  875.  
  876.    *  Unnamed Structures
  877.    *  Named Structures
  878.    *  Other Aspects of Explicitly Specified Structures
  879.  
  880. -------------------------------------------------------------------------------
  881.  
  882. 19.7.1. Unnamed Structures
  883.  
  884. Sometimes a particular data representation is imposed by external requirements,
  885. and yet it is desirable to document the data format as a defstruct-style
  886. structure. For example, consider expressions built up from numbers, symbols,
  887. and binary operations such as + and *. An operation might be represented as it
  888. is in Lisp, as a list of the operator and the two operands. This fact can be
  889. expressed succinctly with defstruct in this manner:
  890.  
  891. (defstruct (binop (:type list))
  892.   (operator '? :type symbol)
  893.   operand-1
  894.   operand-2)
  895.  
  896. This will define a constructor function make-binop and three selector
  897. functions, namely binop-operator, binop-operand-1, and binop-operand-2. (It
  898. will not, however, define a predicate binop-p, for reasons explained below.)
  899.  
  900. The effect of make-binop is simply to construct a list of length 3:
  901.  
  902. (make-binop :operator '+ :operand-1 'x :operand-2 5)
  903.    => (+ x 5)
  904.  
  905. (make-binop :operand-2 4 :operator '*)
  906.    => (* nil 4)
  907.  
  908. It is just like the function list except that it takes keyword arguments and
  909. performs slot defaulting appropriate to the binop conceptual data type.
  910. Similarly, the selector functions binop-operator, binop-operand-1, and
  911. binop-operand-2 are essentially equivalent to car, cadr, and caddr,
  912. respectively. (They might not be completely equivalent because, for example, an
  913. implementation would be justified in adding error-checking code to ensure that
  914. the argument to each selector function is a length-3 list.)
  915.  
  916. We speak of binop as being a ``conceptual'' data type because binop is not made
  917. a part of the Common Lisp type system. The predicate typep will not recognize
  918. binop as a type specifier, and type-of will return list when given a binop
  919. structure. Indeed, there is no way to distinguish a data structure constructed
  920. by make-binop from any other list that happens to have the correct structure.
  921.  
  922. There is not even any way to recover the structure name binop from a structure
  923. created by make-binop. This can be done, however, if the structure is
  924. ``named.''
  925.  
  926. -------------------------------------------------------------------------------
  927.  
  928. 19.7.2. Named Structures
  929.  
  930. A ``named'' structure has the property that, given an instance of the
  931. structure, the structure name (that names the type) can be reliably recovered.
  932. For structures defined with no :type option, the structure name actually
  933. becomes part of the Common Lisp data-type system. The function type-of, when
  934. applied to such a structure, will return the structure name as the type of the
  935. object; the predicate typep will recognize the structure name as a valid type
  936. specifier.
  937.  
  938. For structures defined with a :type option, type-of will return a type
  939. specifier such as list or (vector t), depending on the type specified to the
  940. :type option. The structure name does not become a valid type specifier.
  941. However, if the :named option is also specified, then the first component of
  942. the structure (as created by a defstruct constructor function) will always
  943. contain the structure name. This allows the structure name to be recovered from
  944. an instance of the structure and allows a reasonable predicate for the
  945. conceptual type to be defined: the automatically defined name-p predicate for
  946. the structure operates by first checking that its argument is of the proper
  947. type (list, (vector t), or whatever) and then checking whether the first
  948. component contains the appropriate type name.
  949.  
  950. Consider the binop example shown above, modified only to include the :named
  951. option:
  952.  
  953. (defstruct (binop (:type list) :named)
  954.   (operator '? :type symbol)
  955.   operand-1
  956.   operand-2)
  957.  
  958. As before, this will define a constructor function make-binop and three
  959. selector functions binop-operator, binop-operand-1, and binop-operand-2. It
  960. will also define a predicate binop-p.
  961.  
  962. The effect of make-binop is now to construct a list of length 4:
  963.  
  964. (make-binop :operator '+ :operand-1 'x :operand-2 5)
  965.    => (binop + x 5)
  966.  
  967. (make-binop :operand-2 4 :operator '*)
  968.    => (binop * nil 4)
  969.  
  970. The structure has the same layout as before except that the structure name
  971. binop is included as the first list element. The selector functions
  972. binop-operator, binop-operand-1, and binop-operand-2 are essentially equivalent
  973. to cadr, caddr, and cadddr, respectively. The predicate binop-p is more or less
  974. equivalent to the following definition.
  975.  
  976. (defun binop-p (x)
  977.   (and (consp x) (eq (car x) 'binop)))
  978.  
  979. The name binop is still not a valid type specifier recognizable to typep, but
  980. at least there is a way of distinguishing binop structures from other similarly
  981. defined structures.
  982.  
  983. -------------------------------------------------------------------------------
  984.  
  985. 19.7.3. Other Aspects of Explicitly Specified Structures
  986.  
  987. The :initial-offset option allows one to specify that slots be allocated
  988. beginning at a representational element other than the first. For example, the
  989. form
  990.  
  991. (defstruct (binop (:type list) (:initial-offset 2))
  992.   (operator '? :type symbol)
  993.   operand-1
  994.   operand-2)
  995.  
  996. would result in the following behavior for make-binop:
  997.  
  998. (make-binop :operator '+ :operand-1 'x :operand-2 5)
  999.    => (nil nil + x 5)
  1000. (make-binop :operand-2 4 :operator '*)
  1001.    => (nil nil * nil 4)
  1002.  
  1003. The selectors binop-operator, binop-operand-1, and binop-operand-2 would be
  1004. essentially equivalent to caddr, cadddr, and car of cddddr, respectively.
  1005. Similarly, the form
  1006.  
  1007. (defstruct (binop (:type list) :named (:initial-offset 2))
  1008.   (operator '? :type symbol)
  1009.   operand-1
  1010.   operand-2)
  1011.  
  1012. would result in the following behavior for make-binop:
  1013.  
  1014. (make-binop :operator '+ :operand-1 'x :operand-2 5)
  1015.    => (nil nil binop + x 5)
  1016.  
  1017. (make-binop :operand-2 4 :operator '*)
  1018.    => (nil nil binop * nil 4)
  1019.  
  1020. If the :include is used with the :type option, then the effect is first to skip
  1021. over as many representation elements as needed to represent the included
  1022. structure, then to skip over any additional elements specified by the
  1023. :initial-offset option, and then to begin allocation of elements from that
  1024. point. For example:
  1025.  
  1026. (defstruct (binop (:type list) :named (:initial-offset 2))
  1027.   (operator '? :type symbol)
  1028.   operand-1
  1029.   operand-2)
  1030.  
  1031. (defstruct (annotated-binop (:type list)
  1032.                             (:initial-offset 3)
  1033.                             (:include binop))
  1034.   commutative associative identity)
  1035.  
  1036. (make-annotated-binop :operator '*
  1037.                       :operand-1 'x
  1038.                       :operand-2 5
  1039.                       :commutative t
  1040.                       :associative t
  1041.                       :identity 1)
  1042.    => (nil nil binop * x 5 nil nil nil t t 1)
  1043.  
  1044. The first two nil elements stem from the :initial-offset of 2 in the definition
  1045. of binop. The next four elements contain the structure name and three slots for
  1046. binop. The next three nil elements stem from the :initial-offset of 3 in the
  1047. definition of annotated-binop. The last three list elements contain the
  1048. additional slots for an annotated-binop.
  1049.  
  1050. -------------------------------------------------------------------------------
  1051.  
  1052.  
  1053.  
  1054.